#pragma once
#ifndef __IACTOR_H__
#define __IACTOR_H__

#include <atomic>
#include <disruptorplus/single_threaded_claim_strategy.hpp>
#include <disruptorplus/spin_wait_strategy.hpp>
#include <disruptorplus/ring_buffer.hpp>

#include "EventEngine/IEvent.h"
#include "Common/FastDelegate.h"

namespace NTrader
{
class IActor
{
public:
	typedef std::shared_ptr<IEvent> Event_t;
	typedef fastdelegate::FastDelegate1<Event_t> Handler_t;

	enum ActorStatus
	{
		WAITING = 0,
		EXECUTING,
		EXITED,
	};

	//buffsize must be 2 times
	IActor(size_t buffsize);
	virtual ~IActor() {};

	void SetStatus(int s);
	int GetStatus();

	void SetHandler(Handler_t h) { _inerHandle = h; };
	void RemoveHandler() {_inerHandle = fastdelegate::MakeDelegate(this,&IActor::EventHandler);};

	void Excute();
	void Post(Event_t event);

	//must implement this function by user
	virtual void EventHandler(Event_t event) {};

	std::atomic<int> _status;

private:
	typedef disruptorplus::spin_wait_strategy WS;
	typedef disruptorplus::single_threaded_claim_strategy<WS> CS;

	WS __waitStrategy;
	CS __claimStrategy;
	disruptorplus::sequence_barrier<WS> __consumed;
	disruptorplus::ring_buffer<Event_t> __buffer;

	disruptorplus::sequence_t __nextToRead;

	Handler_t _inerHandle;
};

}

#endif

